package news

import (
	models "HeadLineNews/proto_models/manage/news_model"
	"HeadLineNews/resp"
	"github.com/gin-gonic/gin"
)

type Server interface {
	AddNewsHandler(c *gin.Context)
	UpdateNewsHandler(c *gin.Context)
	RetrieveNewsHandler(c *gin.Context)
	ListNewsHandler(c *gin.Context)
}

type server struct {
	repo Repo
	ctx  Ctx
}

func NewServer() Server {
	return &server{
		repo: NewRepo(),
		ctx:  NewCtx(),
	}
}

// AddNewsHandler 新增新闻
func (s *server) AddNewsHandler(c *gin.Context) {
	// 解析参数
	p, err := s.ctx.ParseParamAddNews(c)
	if err != nil {
		return
	}
	// 检查唯一标题
	if err = s.repo.CheckUniqueNewsName(c, p.NewsTitle); err != nil {
		return
	}
	// 检查合法分类
	if err = s.repo.CheckCategoryExists(c, p.CategoryId); err != nil {
		return
	}
	// 检查合法的作者
	if err = s.repo.CheckAuthorsExist(c, p.Authors); err != nil {
		return
	}
	// 入库
	if err = s.repo.InsertNews(c, p); err != nil {
		return
	}
	resp.Success(c, nil)
}

// UpdateNewsHandler 更新新闻
func (s *server) UpdateNewsHandler(c *gin.Context) {
	// 解析参数
	p, err := s.ctx.ParseParamUpdateNews(c)
	if err != nil {
		return
	}
	// 检查新闻是否存在
	var newsTitle string
	if newsTitle, err = s.repo.CheckNewsExists(c, p.NewsId); err != nil {
		return
	}
	// 检查分类是否存在
	if err = s.repo.CheckCategoryExists(c, p.CategoryId); err != nil {
		return
	}
	// 检查作者是否合法
	if len(p.Authors) != 0 {
		if err = s.repo.CheckAuthorsExist(c, p.Authors); err != nil {
			return
		}
	}
	// 检查新的 title 是否重名
	if newsTitle != p.NewsTitle {
		if err = s.repo.CheckUniqueNewsName(c, p.NewsTitle); err != nil {
			return
		}
	}
	// 更新
	if err = s.repo.UpdateNews(c, p); err != nil {
		return
	}
	resp.Success(c, nil)
}

// RetrieveNewsHandler 检索单条新闻
func (s *server) RetrieveNewsHandler(c *gin.Context) {
	p, err := s.repo.RetrieveNews(c)
	if err != nil {
		return
	}
	resp.Success(c, p)
}

// ListNewsHandler 新闻搜索结果
func (s *server) ListNewsHandler(c *gin.Context) {
	p, err := s.ctx.ParseParamListNews(c)
	if err != nil {
		return
	}
	var data *models.ResponseListNews
	if data, err = s.repo.ListNews(c, p); err != nil {
		return
	}
	resp.Success(c, data)
}
